function drawEntity(gl, shaderProgramInfo, buffer, matrixInfo) {

    if (shaderProgramInfo.kind == 1) {
        drawEntityWithLight(gl, shaderProgramInfo, buffer, matrixInfo);
        return;
    }

    if (shaderProgramInfo.kind == 2) {
        drawEntityWithTexture(gl, shaderProgramInfo, buffer, matrixInfo);
        return;
    }

    //绑定位置
    {
        gl.bindBuffer(gl.ARRAY_BUFFER, buffer.position);
        gl.vertexAttribPointer(
            shaderProgramInfo.attribLocations.vertexPosition,
            3, gl.FLOAT, false, 0, 0
        );
        gl.enableVertexAttribArray(shaderProgramInfo.attribLocations.vertexPosition);
    }

    //绑定颜色
    {
        gl.bindBuffer(gl.ARRAY_BUFFER, buffer.color);
        gl.vertexAttribPointer(
            shaderProgramInfo.attribLocations.vertexColor,
            4, gl.FLOAT, false, 0, 0
        );
        gl.enableVertexAttribArray(shaderProgramInfo.attribLocations.vertexColor);
    }

    //绑定面片
    gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, buffer.surface);

    gl.useProgram(shaderProgramInfo.program);

    gl.uniformMatrix4fv(
        shaderProgramInfo.uniformLocations.projectionMatrix,
        false,
        matrixInfo.projectionMatrix
    );

    gl.uniformMatrix4fv(
        shaderProgramInfo.uniformLocations.modelViewMatrix,
        false,
        matrixInfo.modelViewMatrix
    );

    gl.drawElements(buffer.drawmode, buffer.drawcount, gl.UNSIGNED_SHORT, 0);
}

function drawEntityWithLight(gl, shaderProgramInfo, buffer, matrixInfo) {

    //绑定位置
    {
        gl.bindBuffer(gl.ARRAY_BUFFER, buffer.position);
        gl.vertexAttribPointer(
            shaderProgramInfo.attribLocations.vertexPosition,
            3, gl.FLOAT, false, 0, 0
        );
        gl.enableVertexAttribArray(shaderProgramInfo.attribLocations.vertexPosition);
    }

    //绑定颜色
    {
        gl.bindBuffer(gl.ARRAY_BUFFER, buffer.color);
        gl.vertexAttribPointer(
            shaderProgramInfo.attribLocations.vertexColor,
            4, gl.FLOAT, false, 0, 0
        );
        gl.enableVertexAttribArray(shaderProgramInfo.attribLocations.vertexColor);
    }

    //绑定法矢
    {
        gl.bindBuffer(gl.ARRAY_BUFFER, buffer.normal);
        gl.vertexAttribPointer(
            shaderProgramInfo.attribLocations.vertexNormal,
            3, gl.FLOAT, false, 0, 0
        );
        gl.enableVertexAttribArray(shaderProgramInfo.attribLocations.vertexNormal);
    }

    //绑定面片
    gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, buffer.surface);

    gl.useProgram(shaderProgramInfo.program);

    gl.uniformMatrix4fv(
        shaderProgramInfo.uniformLocations.projectionMatrix,
        false,
        matrixInfo.projectionMatrix
    );

    gl.uniformMatrix4fv(
        shaderProgramInfo.uniformLocations.modelViewMatrix,
        false,
        matrixInfo.modelViewMatrix
    );

    gl.uniformMatrix4fv(
        shaderProgramInfo.uniformLocations.normalMatrix,
        false,
        matrixInfo.normalMatrix
    );

    gl.drawElements(buffer.drawmode, buffer.drawcount, gl.UNSIGNED_SHORT, 0);
}

function drawEntityWithTexture(gl, shaderProgramInfo, buffer, matrixInfo) {
    //绑定位置
    {
        gl.bindBuffer(gl.ARRAY_BUFFER, buffer.position);
        gl.vertexAttribPointer(
            shaderProgramInfo.attribLocations.vertexPosition,
            3, gl.FLOAT, false, 0, 0
        );
        gl.enableVertexAttribArray(shaderProgramInfo.attribLocations.vertexPosition);
    }

    //设置纹理
    {
        var textureLocation = shaderProgramInfo.uniformLocations.texture;

        var texture = gl.createTexture();
        gl.bindTexture(gl.TEXTURE_CUBE_MAP, texture);

        const ctx = document.createElement("canvas").getContext("2d");

        ctx.canvas.width = 128;
        ctx.canvas.height = 128;

        const faceInfos = [
            { target: gl.TEXTURE_CUBE_MAP_POSITIVE_X, faceColor: '#F00', textColor: '#0FF', text1: '许文冲', text2: '19375332' },
            { target: gl.TEXTURE_CUBE_MAP_NEGATIVE_X, faceColor: '#FF0', textColor: '#00F', text1: '许文冲', text2: '19375332' },
            { target: gl.TEXTURE_CUBE_MAP_POSITIVE_Y, faceColor: '#0F0', textColor: '#F0F', text1: '许文冲', text2: '19375332' },
            { target: gl.TEXTURE_CUBE_MAP_NEGATIVE_Y, faceColor: '#0FF', textColor: '#F00', text1: '许文冲', text2: '19375332' },
            { target: gl.TEXTURE_CUBE_MAP_POSITIVE_Z, faceColor: '#00F', textColor: '#FF0', text1: '许文冲', text2: '19375332' },
            { target: gl.TEXTURE_CUBE_MAP_NEGATIVE_Z, faceColor: '#F0F', textColor: '#0F0', text1: '许文冲', text2: '19375332' },
        ];

        faceInfos.forEach((faceInfo) => {
            const {target, faceColor, textColor, text1, text2} = faceInfo;
            generateFace(ctx, faceColor, textColor, text1, text2);

            const level = 0;
            const internalFormat = gl.RGBA;
            const format = gl.RGBA;
            const type = gl.UNSIGNED_BYTE;
            gl.texImage2D(target, level, internalFormat, format, type, ctx.canvas);
        });

        gl.generateMipmap(gl.TEXTURE_CUBE_MAP);
        gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MIN_FILTER, gl.LINEAR_MIPMAP_LINEAR);
    }

    //绑定面片
    gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, buffer.surface);

    gl.useProgram(shaderProgramInfo.program);

    gl.uniformMatrix4fv(
        shaderProgramInfo.uniformLocations.projectionMatrix,
        false,
        matrixInfo.projectionMatrix
    );

    gl.uniformMatrix4fv(
        shaderProgramInfo.uniformLocations.modelViewMatrix,
        false,
        matrixInfo.modelViewMatrix
    );

    gl.uniform1i(textureLocation, 0);

    gl.drawElements(buffer.drawmode, buffer.drawcount, gl.UNSIGNED_SHORT, 0);
}

function generateFace(ctx, faceColor, textColor, text1, text2) {
    const {width, height} = ctx.canvas;
    ctx.fillStyle = faceColor;
    ctx.fillRect(0, 0, width, height);
    ctx.font = `${width * 0.2}px sans-serif`;
    ctx.textAlign = 'center';
    ctx.textBaseline = 'middle';
    ctx.fillStyle = textColor;
    ctx.fillText(text1, width / 2, height / 3);
    ctx.fillText(text2, width / 2, height * 2 / 3);
}